#pragma once

#include <vector>
#include <string.h>

#include <mysql.h>

#include "topdbs_common.hpp"

struct st_mysql;
struct st_mysql_res;
struct st_mysql_bind;
struct st_mysql_stmt;

/*
typedef struct st_mysql MYSQL;  
typedef struct st_mysql_res MYSQL_RES;
typedef struct st_mysql_bind  MYSQL_BIND;
typedef struct st_mysql_stmt MYSQL_STMT;
*/

namespace topdbs
{
	#define Mysql_alloc(p,t,c) (p = (t*)malloc( sizeof(t) * (c) ))
	#define Mysql_max_nums   256

	typedef enum { 
		INTTYPE=0,
		FLOATTYPE,
		DOUBLETYPE,
		CHARTYPE,
		BLOBTYPE 
	} MYSQLPARAM_TYPE;

	typedef struct { 
		char* xpBuf;
		int xSize;
	}T_MYSQL_BUF;

	typedef struct {
		int xCnt;
		int xMax;
		MYSQL_BIND*    xpBind;
		unsigned long* xpLen;
		bool* xpIsNull;
	}T_MYSQL_BIND;

	typedef struct {
		MYSQL_RES*   xpRes;
		T_MYSQL_BIND xParamBind;
		T_MYSQL_BIND xColumnBind;
		T_MYSQL_BUF  xBuf;
		bool xStore;
	}T_MYSQL_STMT;

	struct MyCursor
	{
		MYSQL_STMT*   m_stmt;
		T_MYSQL_STMT* m_sqlstmt;
		std::string m_sqltext;
		MyCursor():m_stmt(nullptr),m_sqlstmt(nullptr) {};
		~MyCursor();
	}; 

	struct MyStmtment {
		MYSQL_STMT* 	m_stmt;
		T_MYSQL_STMT*   m_sqlstmt;
		MYSQL*  m_connection_ptr;
		MyStmtment():m_stmt(nullptr),m_sqlstmt(nullptr),m_connection_ptr(nullptr) {};
		~MyStmtment();
	};

	struct MyStream {
		MYSQL_RES*   m_stream_rs;
		MYSQL*  m_connection_ptr;
		MyStream(): m_stream_rs(nullptr),m_connection_ptr(nullptr) {};
		~MyStream();
	};

	int dbsMysqlAlloc(T_MYSQL_STMT* pMysqlStmt);
	int dbsMysqlFree(T_MYSQL_STMT* pMysqlStmt);
	int dbsMysqlBindInit(T_MYSQL_BIND* pMsqlBind,int col);
	int dbsMysqlColumnLength(T_MYSQL_STMT* pMysqlStmt,int col);
	int dbsMysqlColumnLengths(T_MYSQL_STMT* pMysqlStmt);
	int dbsMysqlBindColumn(T_MYSQL_STMT* pMysqlStmt,int col,char* pBuf,int size,int type);
	int dbsMysqlColumnStrings(T_MYSQL_STMT* pMysqlStmt,char* pBuf,int size);
	int dbsMysqlBindColumnBuffer(T_MYSQL_STMT* pMysqlStmt);
	int dbsMysqlBindParamBuffer(T_MYSQL_STMT* pMysqlStmt);

	int  cvtGetMysqlErr(MYSQL* pMysql,string& erorcd,string& erortx);
	int  cvtGetMysqlErr(MYSQL_STMT* pStmt,string& erorcd,string& erortx);
	int  mysql_param_parse(const std::string& paramFormat,std::vector<MYSQLPARAM_TYPE>& paramType);
}

